#include <stdio.h>
#include "base/abc/abc.h"
#include "base/main/main.h"
#include "app.h"
#include "sat/cnf/cnf.h"
// 文件声明
static int Abc_CommandApp(Abc_Frame_t *pAbc, int argc, char **argv);

//app文件加入到mainlnt声明设置，说明功能即操作名称
extern "C" void App_Init(Abc_Frame_t *pAbc)
{
    Cmd_CommandAdd(pAbc, "approximate for network", "app", Abc_CommandApp, 0);
}
void Abc_FrameClearDesign()
{
}
extern "C" void App_End(Abc_Frame_t *pAbc)
{
    Abc_FrameClearDesign();
    Cnf_ManFree();
    Abc_NtkFraigStoreClean();
    if (Abc_NtkRecIsRunning3())
        Abc_NtkRecStop3();
}
//近似命令交互界面设置
int Abc_CommandApp(Abc_Frame_t *pAbc, int argc, char **argv)
{
    double bound = 0;
    int c;
    int errormodule = 0;
    int module = 0;
    extern Abc_Ntk_t *App_MainAlgorithm(Abc_Ntk_t * pNtk, int module, double bound, int errormodule);
    Abc_Ntk_t *pNtk;
    pNtk = Abc_FrameReadNtk(pAbc);
    if (pNtk == NULL)
    {
        goto usage;
    }
    // set defaults
    bound = 0.01;
    errormodule = 0;
    module = 0;
    Extra_UtilGetoptReset();
    while ((c = Extra_UtilGetopt(argc, argv, "temh")) != EOF)
    {
        switch (c)
        {
        case 't':
            if (globalUtilOptind >= argc)
            {
                Abc_Print(-1, "Command line switch \"-b\" should be followed by an integer.\n");
                goto usage;
            }
            module = atoi(argv[globalUtilOptind]);
            globalUtilOptind++;
            if (module < 0 && module > 1)
                goto usage;
            break;
        case 'e':
            if (globalUtilOptind >= argc)
            {
                Abc_Print(-1, "Command line switch \"-e\" should be followed by a floating point number.\n");
                break;
            }
            bound = (double)atof(argv[globalUtilOptind]);
            globalUtilOptind++;
            if (bound < 0)
                goto usage;
            break;
        case 'm':
            if (globalUtilOptind >= argc)
            {
                Abc_Print(-1, "Command line switch \"-b\" should be followed by an integer.\n");
                goto usage;
            }
            errormodule = atoi(argv[globalUtilOptind]);
            globalUtilOptind++;
            if (errormodule < 0)
                goto usage;
            break;
        case 'h':
            goto usage;
        default:
            goto usage;
        }
    }

    if (bound > 1 || bound < 0)
    {
        Abc_Print(-1, "the limit for error rate range is %.2f \n ", 0.20);
        return 0;
    }
    /*  复制读取的电路，并对复制的电路进行近似替换得到近似电路，若不进行复制，
    则Abc_FrameReplaceCurrentNetwork函数会直接释放我们近似的电路，无法进行电路替换会报错 */
    pNtk = App_MainAlgorithm(Abc_NtkDup(pNtk), module, bound, errormodule);
    Abc_FrameReplaceCurrentNetwork(pAbc, pNtk);
    return 0;

usage:
    Abc_Print(-2, "usage: app [-temh]\n");
    Abc_Print(-2, "\t           approximate the network by BDDs and miter\n");
    Abc_Print(-2, "\t-t         choose the er Optimization mode -0 area -1 delay[default = %d]\n", 0);
    Abc_Print(-2, "\t-e range : the error rate range (0.00 <= range <= 1.00) [default = %.2f]\n", 0.01);
    Abc_Print(-2, "\t-m         choose the er module -0 er -1 amer[default = %d]\n", 0);
    Abc_Print(-2, "\t-h       : prints the command usage\n");
    return 1;
}